package entityManager

import (
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntityManager"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEnv"
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedisService"
	"gitee.com/fierce_wolf/go-fox-edge-common/commSql"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/FileName"
	"gitee.com/fierce_wolf/go-fox-edge-common/edgeEntity"
	_ "github.com/go-sql-driver/mysql" //具体使用的时候，请在服务中，某个go文件中import这一句话
	_ "github.com/mattn/go-sqlite3"    //具体使用的时候，请在服务中，某个go文件中import这一句话
	"io/ioutil"
	"strings"
)

func Instance() {
	consumer := commRedisService.IRedisManager.GetRedisConsumer()
	reader := commRedisService.IRedisManager.GetRedisReader()
	writer := commRedisService.IRedisManager.GetRedisWriter()

	// 注册数据库实体	
	commSql.Register(edgeEntity.Type.DeviceEntity.Type())
	commSql.Register(edgeEntity.Type.ChannelEntity.Type())
	commSql.Register(edgeEntity.Type.ConfigEntity.Type())
	commSql.Register(edgeEntity.Type.UserEntity.Type())
	commSql.Register(edgeEntity.Type.UserMenuEntity.Type())
	commSql.Register(edgeEntity.Type.UserRoleEntity.Type())
	commSql.Register(edgeEntity.Type.UserPermissionEntity.Type())
	commSql.Register(edgeEntity.Type.DeviceObjectEntity.Type())
	commSql.Register(edgeEntity.Type.DeviceMapperEntity.Type())
	commSql.Register(edgeEntity.Type.DeviceModelEntity.Type())
	commSql.Register(edgeEntity.Type.DeviceTemplateEntity.Type())
	commSql.Register(edgeEntity.Type.ExtendConfigEntity.Type())
	commSql.Register(edgeEntity.Type.DeviceRecordEntity.Type())
	commSql.Register(edgeEntity.Type.DeviceValueExTaskEntity.Type())
	commSql.Register(edgeEntity.Type.OperateRecordEntity.Type())
	commSql.Register(edgeEntity.Type.OperateMonitorTaskEntity.Type())
	commSql.Register(edgeEntity.Type.OperateManualTaskEntity.Type())
	commSql.Register(edgeEntity.Type.OperateChannelTaskEntity.Type())
	commSql.Register(edgeEntity.Type.OperateEntity.Type())
	commSql.Register(edgeEntity.Type.IotDeviceModelEntity.Type())
	commSql.Register(edgeEntity.Type.IotTemplateEntity.Type())
	commSql.Register(edgeEntity.Type.RepoCompEntity.Type())
	commSql.Register(edgeEntity.Type.DeviceHistoryEntity.Type())

	// 告知：生产者如何装载数据源
	commEntityManager.EntityManager.SourceTypes[edgeEntity.Type.DeviceEntity.Type()] = nil
	commEntityManager.EntityManager.SourceTypes[edgeEntity.Type.ChannelEntity.Type()] = nil
	commEntityManager.EntityManager.SourceTypes[edgeEntity.Type.ConfigEntity.Type()] = nil
	commEntityManager.EntityManager.SourceTypes[edgeEntity.Type.UserEntity.Type()] = nil
	commEntityManager.EntityManager.SourceTypes[edgeEntity.Type.UserMenuEntity.Type()] = nil
	commEntityManager.EntityManager.SourceTypes[edgeEntity.Type.UserRoleEntity.Type()] = nil
	commEntityManager.EntityManager.SourceTypes[edgeEntity.Type.UserPermissionEntity.Type()] = nil
	commEntityManager.EntityManager.SourceTypes[edgeEntity.Type.ExtendConfigEntity.Type()] = nil
	commEntityManager.EntityManager.SourceTypes[edgeEntity.Type.DeviceValueExTaskEntity.Type()] = nil
	commEntityManager.EntityManager.SourceTypes[edgeEntity.Type.OperateEntity.Type()] = nil
	commEntityManager.EntityManager.SourceTypes[edgeEntity.Type.OperateMonitorTaskEntity.Type()] = nil
	commEntityManager.EntityManager.SourceTypes[edgeEntity.Type.OperateManualTaskEntity.Type()] = nil
	commEntityManager.EntityManager.SourceTypes[edgeEntity.Type.OperateChannelTaskEntity.Type()] = nil
	commEntityManager.EntityManager.SourceTypes[edgeEntity.Type.DeviceMapperEntity.Type()] = nil
	commEntityManager.EntityManager.SourceTypes[edgeEntity.Type.DeviceModelEntity.Type()] = nil
	commEntityManager.EntityManager.SourceTypes[edgeEntity.Type.DeviceTemplateEntity.Type()] = nil
	commEntityManager.EntityManager.SourceTypes[edgeEntity.Type.IotDeviceModelEntity.Type()] = nil
	commEntityManager.EntityManager.SourceTypes[edgeEntity.Type.IotTemplateEntity.Type()] = nil
	commEntityManager.EntityManager.SourceTypes[edgeEntity.Type.RepoCompEntity.Type()] = nil

	// 注册redis操作
	consumer[edgeEntity.Type.OperateMethodEntity.Type()] = nil
	consumer[edgeEntity.Type.DeviceObjInfEntity.Type()] = nil

	reader[edgeEntity.Type.ChannelStatusEntity.Type()] = nil
	reader[edgeEntity.Type.DeviceValueEntity.Type()] = nil
	reader[edgeEntity.Type.DeviceValueExEntity.Type()] = nil
	reader[edgeEntity.Type.DeviceStatusEntity.Type()] = nil
	reader[edgeEntity.Type.OperateMethodEntity.Type()] = nil

	reader[edgeEntity.Type.DeviceEntity.Type()] = nil
	writer[edgeEntity.Type.DeviceEntity.Type()] = nil
	reader[edgeEntity.Type.OperateEntity.Type()] = nil
	writer[edgeEntity.Type.OperateEntity.Type()] = nil
	reader[edgeEntity.Type.RepoCompEntity.Type()] = nil
	writer[edgeEntity.Type.RepoCompEntity.Type()] = nil
	reader[edgeEntity.Type.DeviceModelEntity.Type()] = nil
	writer[edgeEntity.Type.DeviceModelEntity.Type()] = nil
	reader[edgeEntity.Type.DeviceTemplateEntity.Type()] = nil
	writer[edgeEntity.Type.DeviceTemplateEntity.Type()] = nil
	reader[edgeEntity.Type.DeviceMapperEntity.Type()] = nil
	writer[edgeEntity.Type.DeviceMapperEntity.Type()] = nil
	reader[edgeEntity.Type.OperateMonitorTaskEntity.Type()] = nil
	writer[edgeEntity.Type.OperateMonitorTaskEntity.Type()] = nil
	reader[edgeEntity.Type.OperateManualTaskEntity.Type()] = nil
	writer[edgeEntity.Type.OperateManualTaskEntity.Type()] = nil
	reader[edgeEntity.Type.OperateChannelTaskEntity.Type()] = nil
	writer[edgeEntity.Type.OperateChannelTaskEntity.Type()] = nil
	reader[edgeEntity.Type.ChannelEntity.Type()] = nil
	writer[edgeEntity.Type.ChannelEntity.Type()] = nil
	reader[edgeEntity.Type.ConfigEntity.Type()] = nil
	writer[edgeEntity.Type.ConfigEntity.Type()] = nil
	reader[edgeEntity.Type.IotDeviceModelEntity.Type()] = nil
	writer[edgeEntity.Type.IotDeviceModelEntity.Type()] = nil
	reader[edgeEntity.Type.IotTemplateEntity.Type()] = nil
	writer[edgeEntity.Type.IotTemplateEntity.Type()] = nil
	reader[edgeEntity.Type.UserEntity.Type()] = nil
	writer[edgeEntity.Type.UserEntity.Type()] = nil
	reader[edgeEntity.Type.UserMenuEntity.Type()] = nil
	writer[edgeEntity.Type.UserMenuEntity.Type()] = nil
	reader[edgeEntity.Type.UserRoleEntity.Type()] = nil
	writer[edgeEntity.Type.UserRoleEntity.Type()] = nil
	reader[edgeEntity.Type.UserPermissionEntity.Type()] = nil
	writer[edgeEntity.Type.UserPermissionEntity.Type()] = nil
	reader[edgeEntity.Type.ExtendConfigEntity.Type()] = nil
	writer[edgeEntity.Type.ExtendConfigEntity.Type()] = nil
	reader[edgeEntity.Type.DeviceValueExTaskEntity.Type()] = nil
	writer[edgeEntity.Type.DeviceValueExTaskEntity.Type()] = nil
}

func InitLoadEntity() {
	// 初始化MYSQL/SQLite的数据库连接
	initDBConnect()

	commEntityManager.InitLoadEntity()
}

// Scheduler 线程函数
func Scheduler() {
	commEntityManager.Scheduler()
}

func initDBConnect() {
	// 连接MYSQL数据库
	if commSql.GetDBType() == "mysql" {
		err := commSql.Client.ConnectMySQL()
		if err != nil {
			panic("连接数据库失败:" + err.Error())
		}
		return
	}

	// 连接SQLite3数据库
	if commSql.GetDBType() == "sqlite3" {
		// 打开数据库
		err := commSql.Client.ConnectSQLite("fox-edge.db")
		if err != nil {
			panic("连接数据库失败:" + err.Error())
		}

		// 读取初始化脚本的内容
		initDBBySQLite3File("/sql/init_sqlite3.sql")
		initDBBySQLite3File("/sql/init_sqlite3_data.sql")

		return
	}
}

func initDBBySQLite3File(sqlite3File string) {
	// 读取初始化脚本的内容
	filePath := FileName.GetOsFilePath(commEnv.Service.WorkDir + sqlite3File)
	ctx, err := ioutil.ReadFile(filePath)
	if err != nil {
		return
	}

	// 根据分号分拆SQL语句
	sqls := strings.Split(string(ctx), ";\r\n")

	// 逐个执行sql语句
	for _, sql := range sqls {
		sql = strings.TrimPrefix(sql, "\r\n")
		sql = strings.TrimPrefix(sql, "\t\t")
		if sql == "" {
			continue
		}
		commSql.Client.Exec(sql+";", nil)
	}
}
